<template>
  <m-window-frame
    :title="title"
    style="height: 100%"
    class="v-choose-dir-window"
    :okText="'确 定'"
    :confirmDisabled="!canConfirm"
    :cancel-text="'取 消'"
    @cancel="handleCancel"
    @ok="handleSave"
  >
    <attr-tips :type="attrTip"></attr-tips>
    <div class="choose-dir-container">
      <div
        class="g-pd-lr-20 g-pd-b-20 g-pd-t-10"
        style="height: 100%; width: 100%"
      >
        <SelectTree
          :treeData="treeData"
          :lazy="lazy"
          :customLoadResult="false"
          :loadNodes="loadTree"
          @handleNodeClick="handleTreeNodeClick"
        ></SelectTree>
      </div>
    </div>
  </m-window-frame>
</template>

<script lang="ts" setup>
import MWindowFrame from "@/common/ipcWindow/WindowFrame.vue";
import { ref, watch, computed, onBeforeMount } from "vue";
import { useRoute } from "vue-router";
import AttrTips from "@/common/attrTip/AttrTip.vue";
import { Params, CloseData } from "./index";
import { MTreeNode } from "@/common/Tree/MTreeNode";
import SelectTree from "@/modules/model/modals/modelTreeSelect/components/SelectTree.vue";
import { ipcWindowUtil } from "@/mdesign-lib/mdesign-app.umd.js";
import { rmi } from "@/util/IpcWindow/RMI";

interface TreeItem extends MTreeNode {
  id: number | string;
  icon: string;
  children: TreeItem[];
  loaded: boolean;
  name: string;
  hasChildren?: boolean;
}

const title = ref("");
const attrTip = ref("");
let methodPath = "";
let idName = "";
let isLeafName = "";
let labelName = "";
let params: any[] = [];

const lazy = ref(false);

const route = useRoute();
const treeData = ref<TreeItem[]>([]);
const selectedTreeNode = ref<MTreeNode>();
const selectedTreeId = ref<number>();
const canConfirm = computed(() => selectedTreeNode.value);

watch(
  () => route.fullPath,
  async () => {
    const routeQuery = route.query as unknown;
    const query = routeQuery as Params;
    title.value = query.title;
    attrTip.value = query.attrTip;
    methodPath = query.methodPath;
    idName = query.idName || "id";
    isLeafName = query.isLeafName || "isLeaf";
    labelName = query.labelName || "name";
    params = query.params || [];
    lazy.value = query.lazy === "true";
  },
  { immediate: true }
);

onBeforeMount(async () => {
  loadTree();
});

const loadTree = async (dir?: TreeItem) => {
  if (!dir) {
    treeData.value = await getTreeItem();
  } else {
    const children = await getTreeItem(dir.id);
    return children;
  }
};

const getTreeItem = async (id?: number | string) => {
  const res = (await rmi.invoke(methodPath, [...params, id])) as any[];
  const data = res.map(treeItem => {
    return formatTreeItem(treeItem);
  });
  return data;
};

const formatTreeItem = (treeItem: any) => {
  const item: TreeItem = {
    id: treeItem[idName],
    icon: "statics/images/sysml/package.png",
    children: treeItem.children.map(it => formatTreeItem(it)),
    expand: false,
    loaded: false,
    isLeaf: treeItem[isLeafName],
    name: treeItem[labelName],
    data: treeItem,
    selected: false
  };
  return item;
};

// const getChildren = (node: MTreeNode) => {
//   return node.children.filter((item) => item.show !== false);
// };

// async function searchTree(node: TreeItem | TreeItem[], parent: TreeItem | null | undefined, depth = 0, callback: (node: TreeItem, parent: TreeItem | null | undefined, depth: number) => Promise<TreeItem[] | void>) {
//   if (Array.isArray(node)) {
//     for (let i = 0; i < node.length; i++) {
//       const child = node[i];
//       await searchTree(child, parent, depth, callback);
//     }
//   } else {
//     const children = await callback(node, parent, depth);
//     depth++;
//     if (children) {
//       await searchTree(children, node, depth, callback);
//     }
//   }
// }

// const handleExpand = async (node: MTreeNode) => {
//   const loaded = node.loaded;
//   if (!loaded && node.hasChildren !== false) {
//     await loadTree(node as TreeItem);
//   }

//   node.loaded = true;
// };

const handleTreeNodeClick = (node: MTreeNode) => {
  if (selectedTreeNode.value !== node) {
    if (selectedTreeNode.value) {
      selectedTreeNode.value.selected = false;
    }
    node.selected = true;
    selectedTreeNode.value = node;
    selectedTreeId.value = node.id as number;
  }
};

const handleSave = () => {
  const result = { ...selectedTreeNode.value?.data };
  delete result.children;
  handleclose({ success: true, info: result });
};

function handleclose(data: CloseData) {
  ipcWindowUtil.closeWindow(data);
}
function handleCancel() {
  handleclose({ success: false });
}
</script>
<style lang="scss">
.choose-dir-container {
  flex: 1;
  display: flex;
  overflow: hidden;
}
</style>
